#ifndef __PADDING_H__
#define __PADDING_H__

#include <sys/types.h>

/* Dynamic Switching Headers */
#ifdef __cplusplus
extern "C" {
#endif // __cplusplus

/*
  For __APPLE we can ust use one big block before and after. However
  for __linux__ the linker has separate sections for small and large
  uninitialized data (sbss and bss respectively) so we have to use
  multiple works. The __linux__ code here seems generally less stable,
  so we also try to use a linker script.
*/
#ifdef __APPLE__
#define PADDING(symbol) \
uint symbol##_padding[8192];
#else // !APPLE
#ifdef __linux__
struct Padding {
    uint padding[8192];
};
#define PADDING(symbol) \
uint symbol##_padding_word_0_uninitialized_nonstatic; \
uint symbol##_padding_word_1_uninitialized_nonstatic; \
uint symbol##_padding_word_2_uninitialized_nonstatic; \
uint symbol##_padding_word_3_uninitialized_nonstatic; \
uint symbol##_padding_word_4_uninitialized_nonstatic; \
uint symbol##_padding_word_5_uninitialized_nonstatic; \
uint symbol##_padding_word_6_uninitialized_nonstatic; \
uint symbol##_padding_word_7_uninitialized_nonstatic; \
uint symbol##_padding_word_8_uninitialized_nonstatic; \
uint symbol##_padding_word_9_uninitialized_nonstatic; \
uint symbol##_padding_word_a_uninitialized_nonstatic; \
uint symbol##_padding_word_b_uninitialized_nonstatic; \
uint symbol##_padding_word_c_uninitialized_nonstatic; \
uint symbol##_padding_word_d_uninitialized_nonstatic; \
uint symbol##_padding_word_e_uninitialized_nonstatic; \
uint symbol##_padding_word_f_uninitialized_nonstatic; \
uint symbol##_padding_word_0_initialized_nonstatic = 0; \
uint symbol##_padding_word_1_initialized_nonstatic = 0; \
uint symbol##_padding_word_2_initialized_nonstatic = 0; \
uint symbol##_padding_word_3_initialized_nonstatic = 0; \
uint symbol##_padding_word_4_initialized_nonstatic = 0; \
uint symbol##_padding_word_5_initialized_nonstatic = 0; \
uint symbol##_padding_word_6_initialized_nonstatic = 0; \
uint symbol##_padding_word_7_initialized_nonstatic = 0; \
uint symbol##_padding_word_8_initialized_nonstatic = 0; \
uint symbol##_padding_word_9_initialized_nonstatic = 0; \
uint symbol##_padding_word_a_initialized_nonstatic = 0; \
uint symbol##_padding_word_b_initialized_nonstatic = 0; \
uint symbol##_padding_word_c_initialized_nonstatic = 0; \
uint symbol##_padding_word_d_initialized_nonstatic = 0; \
uint symbol##_padding_word_e_initialized_nonstatic = 0; \
uint symbol##_padding_word_f_initialized_nonstatic = 0; \
struct Padding symbol##_padding_struct_0; \
struct Padding symbol##_padding_struct_1; \
struct Padding symbol##_padding_struct_2; \
struct Padding symbol##_padding_struct_3; \
struct Padding symbol##_padding_struct_4; \
struct Padding symbol##_padding_struct_5; \
struct Padding symbol##_padding_struct_6; \
struct Padding symbol##_padding_struct_7; \
struct Padding symbol##_padding_struct_8; \
struct Padding symbol##_padding_struct_9; \
struct Padding symbol##_padding_struct_a; \
struct Padding symbol##_padding_struct_b; \
struct Padding symbol##_padding_struct_c; \
struct Padding symbol##_padding_struct_d; \
struct Padding symbol##_padding_struct_e; \
struct Padding symbol##_padding_struct_f; \
static uint symbol##_padding_word_0_uninitialized_static; \
static uint symbol##_padding_word_1_uninitialized_static; \
static uint symbol##_padding_word_2_uninitialized_static; \
static uint symbol##_padding_word_3_uninitialized_static; \
static uint symbol##_padding_word_4_uninitialized_static; \
static uint symbol##_padding_word_5_uninitialized_static; \
static uint symbol##_padding_word_6_uninitialized_static; \
static uint symbol##_padding_word_7_uninitialized_static; \
static uint symbol##_padding_word_8_uninitialized_static; \
static uint symbol##_padding_word_9_uninitialized_static; \
static uint symbol##_padding_word_a_uninitialized_static; \
static uint symbol##_padding_word_b_uninitialized_static; \
static uint symbol##_padding_word_c_uninitialized_static; \
static uint symbol##_padding_word_d_uninitialized_static; \
static uint symbol##_padding_word_e_uninitialized_static; \
static uint symbol##_padding_word_f_uninitialized_static; \
static uint symbol##_padding_word_0_initialized_static = 0; \
static uint symbol##_padding_word_1_initialized_static = 0; \
static uint symbol##_padding_word_2_initialized_static = 0; \
static uint symbol##_padding_word_3_initialized_static = 0; \
static uint symbol##_padding_word_4_initialized_static = 0; \
static uint symbol##_padding_word_5_initialized_static = 0; \
static uint symbol##_padding_word_6_initialized_static = 0; \
static uint symbol##_padding_word_7_initialized_static = 0; \
static uint symbol##_padding_word_8_initialized_static = 0; \
static uint symbol##_padding_word_9_initialized_static = 0; \
static uint symbol##_padding_word_a_initialized_static = 0; \
static uint symbol##_padding_word_b_initialized_static = 0; \
static uint symbol##_padding_word_c_initialized_static = 0; \
static uint symbol##_padding_word_d_initialized_static = 0; \
static uint symbol##_padding_word_e_initialized_static = 0; \
static uint symbol##_padding_word_f_initialized_static = 0; \
int symbol##_use_statics_to_prevent_compile_warning () { return \
symbol##_padding_word_0_uninitialized_static+ \
symbol##_padding_word_1_uninitialized_static+ \
symbol##_padding_word_2_uninitialized_static+ \
symbol##_padding_word_3_uninitialized_static+ \
symbol##_padding_word_4_uninitialized_static+ \
symbol##_padding_word_5_uninitialized_static+ \
symbol##_padding_word_6_uninitialized_static+ \
symbol##_padding_word_7_uninitialized_static+ \
symbol##_padding_word_8_uninitialized_static+ \
symbol##_padding_word_9_uninitialized_static+ \
symbol##_padding_word_a_uninitialized_static+ \
symbol##_padding_word_b_uninitialized_static+ \
symbol##_padding_word_c_uninitialized_static+ \
symbol##_padding_word_d_uninitialized_static+ \
symbol##_padding_word_e_uninitialized_static+ \
symbol##_padding_word_f_uninitialized_static+ \
symbol##_padding_word_0_initialized_static+ \
symbol##_padding_word_1_initialized_static+ \
symbol##_padding_word_2_initialized_static+ \
symbol##_padding_word_3_initialized_static+ \
symbol##_padding_word_4_initialized_static+ \
symbol##_padding_word_5_initialized_static+ \
symbol##_padding_word_6_initialized_static+ \
symbol##_padding_word_7_initialized_static+ \
symbol##_padding_word_8_initialized_static+ \
symbol##_padding_word_9_initialized_static+ \
symbol##_padding_word_a_initialized_static+ \
symbol##_padding_word_b_initialized_static+ \
symbol##_padding_word_c_initialized_static+ \
symbol##_padding_word_d_initialized_static+ \
symbol##_padding_word_e_initialized_static+ \
symbol##_padding_word_f_initialized_static+ \
0;}
#else // !__linux__
#ifdef _AIX
#define PADDING(symbol) \
/* This space intentionally left blank */
#else
#error unsupported OS
#endif // !_AIX
#endif // !__linux__
#endif // !APPLE

#ifdef __cplusplus
};
#endif // __cplusplus

#endif // __PADDING_H__
